package edu.jxufe.nb112.common.code.io;

import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.FileFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by lvxi on 2017/11/12.
 * Note:
 */
public class FileUtils {
    private static final Logger LOG = LoggerFactory.getLogger(FileUtils.class.getName());

    private FileUtils(){

    }

    /**
     * 递归获取目录中的文件，包括所有子目录
     * @param file 文件或目录
     * @return ArrayList文件列表
     */
    public static List<File> listAll(final File file){
        return FileUtils.listAll(file,true,null);
    }

    /**
     * 递归获取目录中的文件，包括所有子目录,如果目录被过滤依然进入子目录
     * @param file 文件或目录
     * @return ArrayList文件列表
     */
    public static List<File> listAll(final File file,final FileFilter fileFilter){
        return FileUtils.listAll(file,true,fileFilter);
    }

    /**
     * 递归获取目录中的文件，包括所有子目录
     * @param file 文件或目录
     * @param fileFilter 过滤器
     * @param isContinue 目录被过滤是否继续进入子目录
     * @return ArrayList文件列表
     */
    public static List<File> listAll(final File file, boolean isContinue,final FileFilter fileFilter){
        List<File> list = new ArrayList<File>();
        if(!file.exists()) {
            return list;
        }
        if(file.isFile()){
            if(fileFilter.accept(file)){
                if(LOG.isDebugEnabled()){
                    LOG.debug(file.getAbsolutePath());
                }
                list.add(file);
            }
            return list;
        }
        File[] childFileList = file.listFiles();
        for (File childFile : childFileList) {
            boolean isAccept =isContinue;
            if(fileFilter==null || fileFilter.accept(childFile)) {
                if(LOG.isDebugEnabled()){
                    LOG.debug(childFile.getAbsolutePath());
                }
                isAccept=true;
                list.add(childFile);
            }
            if(isAccept && childFile.isDirectory()) {
                list.addAll(listAll(childFile,isContinue,fileFilter));
            }
        }
        return list;
    }

    /**
     * 递归获取目录中的文件，包括所有子目录
     * @param file 文件或目录
     * @return
     */
    public static List<File> listAllFiles(final File file) {
        return FileUtils.listAllFiles(file,true,null);
    }

    /**
     * 递归获取目录中的文件，包括所有子目录,如果目录被过滤依然进入子目录
     * @param file 文件或目录
     * @param fileFilter 过滤器
     * @return
     */
    public static List<File> listAllFiles(final File file,final FileFilter fileFilter) {
        return FileUtils.listAllFiles(file,true,fileFilter);
    }

    /**
     * 递归获取目录中的文件，包括所有子目录
     * @param file 文件或目录
     * @param fileFilter 过滤器
     * @param isContinue 目录被过滤是否继续进入子目录
     * @return
     */
    public static List<File> listAllFiles(final File file,boolean isContinue,final FileFilter fileFilter){

        AndFileFilter andFileFilter = new AndFileFilter();
        andFileFilter.addFileFilter(FileFileFilter.FILE);
        andFileFilter.addFileFilter( new IOFileFilter (){

            public boolean accept(File file) {
                if(fileFilter!=null){
                    return fileFilter.accept(file);
                }
                return true;
            }

            public boolean accept(File dir, String name) {
                return false;
            }
        });
        return FileUtils.listAll(file,isContinue,andFileFilter);
    }

    /**
     * 递归获取目录中的目录，包括所有子目录,如果目录被过滤依然进入子目录
     * @param file 目录
     * @return
     */
    public static List<File> listAllDirectory(final File file){
        return FileUtils.listAllDirectory(file,true,null);
    }

    /**
     * 递归获取目录中的目录，包括所有子目录,如果目录被过滤依然进入子目录
     * @param file 目录
     * @param fileFilter 过滤器
     * @return
     */
    public static List<File> listAllDirectory(final File file,final FileFilter fileFilter) {
        return FileUtils.listAllDirectory(file,true,fileFilter);
    }


    /**
     * 获取目录中的目录，包括所有子目录
     * @param file 目录
     * @param fileFilter 过滤器
     * @param isContinue 目录被过滤是否继续进入子目录
     * @return
     */
    public static List<File> listAllDirectory(final File file,boolean isContinue,final FileFilter fileFilter){


        return FileUtils.listAll(file,isContinue,new AndFileFilter(DirectoryFileFilter.DIRECTORY, new IOFileFilter (){

            public boolean accept(File file) {
                if(fileFilter!=null){
                    return fileFilter.accept(file);
                }
                return true;
            }

            public boolean accept(File dir, String name) {
                return false;
            }
        }));
    }
}
